#include "inputdata.h"
#include <iostream>
#include <QString>

InputData::InputData()
{

}

void InputData::readData(const QString& videoName)
{
    int len = videoName.length(), dotPos = len;
    for(int i = 0; i < len; ++i) {
        if(videoName[len - i - 1].toLatin1() == '.') {
            dotPos = i;
            break;
        }
    }
    if(dotPos == len)
        throw "Wrong video name";
    QString pureName = videoName.left(len - dotPos - 1);
    int i = 0;
    for(; i < pureName.length() && pureName[pureName.length() - i - 1].isDigit(); ++i);
    QString numStr = pureName.right(i);
    bool ok = false;
    int fileIndex = numStr.toInt(&ok, 10);
    if(!ok)
        throw "Wrong video name";
    readData(fileIndex);
}

void InputData::readData(int index)
{
    dataIndex = index;
    initFilePath();
    closeFile();
    openFileRead();
    if(pts)
        delete pts;
    pts = new std::map<int64, Points>;
    if(frameId)
        delete frameId;
    fscanf(tipslineFp, "%d", &frameNum);
    frameId = new std::set<int64>;
    for(int i = 0; i < frameNum; ++i) {
        int64 tempTime;
        fscanf(timelineFp, "%lld", &tempTime);
        frameId->insert(tempTime);
    }
    std::set<int64>::iterator it = frameId->begin();
    for(int i = 0 ; i < frameNum; ++i, ++it) {
        int startIndex, endIndex;
        fscanf(tipslineFp, "%d %d", &startIndex, &endIndex);
        int pointsNum = endIndex - startIndex;
        for(int j = 0; j < pointsNum; ++j) {
            int x, y;
            fscanf(tipsPointsFp, "%d %d", &x, &y);
            (*pts)[*it].insert(Pos(x, y));
        }
    }

}



void InputData::writeData()
{
    closeFile();
    openFileWrite();
    fprintf(tipslineFp, "%d\n", frameNum);
    for(std::set<int64>::iterator it = frameId->begin(); it != frameId->end(); it++) {
        fprintf(timelineFp, "%lld\n", *it);
    }
    size_t tipsCount = 0;
    for(std::map<int64, Points>::iterator it = pts->begin(); it != pts->end(); ++it) {
        fprintf(tipslineFp, "%lu %lu\n", tipsCount, tipsCount + it->second.size());
        for(Points::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
            fprintf(tipsPointsFp, "%d %d\n", jt->x, jt->y);
        }
    }

}

void InputData::openFileRead()
{
    timelineFp = fopen(timeLineFilePath.c_str(), "r");
    tipslineFp = fopen(tipslineFilePath.c_str(), "r");
    tipsPointsFp = fopen(tipsPointsFilePath.c_str(), "r");
    if(!timelineFp || !tipslineFp || !tipsPointsFp)
            throw std::ios_base::failure("can not create file");
}

void InputData::closeFile()
{
    if(!timelineFp) {
        fclose(timelineFp);
        timelineFp = nullptr;
    }
    if(!tipslineFp) {
        fclose(tipslineFp);
        timelineFp = nullptr;
    }
    if(!tipsPointsFp) {
        fclose(tipsPointsFp);
        tipsPointsFp = nullptr;
    }
}

void InputData::openFileWrite()
{
    timelineFp = fopen(timeLineFilePath.c_str(), "w");
    tipslineFp = fopen(tipslineFilePath.c_str(), "w");
    tipsPointsFp = fopen(tipsPointsFilePath.c_str(), "w");
    if(!timelineFp || !tipslineFp || !tipsPointsFp)
            throw std::ios_base::failure("can not create file");
}

void InputData::initFilePath()
{
    dataDirPath = Constants::dataDirPath;
    timeLineFilePath = dataDirPath + "/" +  "timeline_" + std::to_string(dataIndex) + ".txt" ;
    tipslineFilePath = dataDirPath + "/" + "tipsline_" + std::to_string(dataIndex) + ".txt";
    tipsPointsFilePath = dataDirPath + "/" + "tippoints_" + std::to_string(dataIndex) + ".txt";

}
